<template>
  <div class="scene-edifice-box">
    <el-form ref="form" :model="formData" :disabled="popConfig.disabled" :rules="rules" label-width="110px">
      <template v-for="(item, index) in formList">
        <el-form-item
          :key="`${item.prop}${index}`"
          :style="item.itemStyle || {}"
          :label="item.name"
          :prop="item.prop"
          :class="item.itemClass"
        >
          <component
            :is="item.componentType || 'el-input'"
            v-if="item.prop"
            v-model="formData[item.prop]"
            :clearable="true"
            :class="item.class"
            v-bind="item.attrConfig || {}"
            @change="handlerSelectData(item)"
            @changeImg="changeImg"
          >
            <template v-for="option in item.optionList">
              <el-option
                :key="option.code"
                :label="option.name"
                :value="option.code"
              />
            </template>
          </component>
          <span v-if="item.prop === 'posX'" style="margin-left: 0.2em;">(X轴)</span>
          <span v-if="item.prop === 'posY'" style="margin-left: 0.2em;">(Y轴)</span>
          <el-popover v-if="item.prop === 'posX'" placement="top-start" trigger="hover" width="280" :content="popoverContent">
            <i slot="reference" class="el-icon-question" style="margin-left: 0.5em;font-size: 18px;"/>
          </el-popover>
        </el-form-item>
      </template>
      <el-form-item v-if="!popConfig.disabled">
        <el-button size="small" @click="generateFloorList">生成楼层列表</el-button>
      </el-form-item>
      <el-form-item></el-form-item>
      <div class="el-form floor-div">
        <!-- 楼层列表 -->
        <template v-for="(item, index) in floorList">
          <el-form-item
            :key="`${item.floorNum}${index}`"
            :label="item.floorNum + '层名称'"
            :prop="`floor_${index}`"
          >
            <el-input v-model="item.floorName" :clearable="true"></el-input>
          </el-form-item>
          <el-form-item label="建筑面积(m²)"
                        :prop="`floor_area_${index}`">
            <el-input-number v-model="item.floorArea" :clearable="true" style="width: 100%"
                             :controls="false"></el-input-number>
          </el-form-item>
        </template>
      </div>
    </el-form>
  </div>
</template>

<script>
import { dictMixin } from '@/mixin/dict'
import api from '@/api/apis/sceneFloor'
import AddImg from '@/components/PopItems/add-img.vue'

export default {
  name: 'AddSceneEdifice',
  mixins: [dictMixin],
  components: { AddImg },
  props: {
    // 请求参数
    requestParams: {
      type: Object,
      default: () => ({})
    },
    // 弹窗数据
    popData: {
      type: Object,
      default: () => ({})
    },
    // 弹窗配置
    popConfig: {
      type: Object,
      default: () => ({})
    },
    // 弹窗取消
    close: {
      type: Boolean,
      default: false
    },
    // 弹窗确认
    confirm: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      isAdd: true,
      formData: {},
      floorAreaMax: 999999,
      floorList: [],
      popoverContent: '1、以可视化平台背景图中间空由区域的左上角为0.0原点，向右延伸为x正数。向左延健为x负数。向下延伸为y轴正数，向上延伸为y轴负数。2、背景图任意位置都可定点。3、单位为rem，1rem=2px(像素)',
      formList: [
        {
          name: '基本信息',
          itemClass: 'lable-head'
        },
        {
          name: ''
        },
        {
          name: '所属项目',
          prop: 'sceneProjectId',
          componentType: 'el-select',
          optionList: [],
          selectPath: 'commonSelected',
          selectParams: {
            code: 'SceneProjectSelected'
          },
          attrConfig: {
            disabled: true,
            placeholder: '请选择所属项目',
            options: []
          },
          dataProp: {
            dataType: 'resData',
            nameProp: 'label',
            codeProp: 'value'
          },
          selectStyle: { width: '180px' }
        },
        {
          name: '楼栋名称',
          prop: 'edificeName',
          attrConfig: { placeholder: '请输入楼栋名称' }
        },
        {
          name: '建筑面积',
          prop: 'floorArea',
          componentType: 'el-input-number',
          attrConfig: {
            style: 'width:100%',
            controls: false,
            placeholder: '请输入建筑面积'
          }
        },
        {},
        {
          name: '定点位置',
          prop: 'posX',
          componentType: 'el-input-number',
          attrConfig: {
            style: 'width:80%',
            controls: false,
            placeholder: '请输入定点位置(X轴)'
          }
        },
        {},
        {
          name: '',
          prop: 'posY',
          componentType: 'el-input-number',
          attrConfig: {
            style: 'width:80%',
            controls: false,
            placeholder: '请输入定点位置(Y轴)'
          }
        },
        {},
        {
          name: '弹窗位置',
          prop: 'popPosition',
          componentType: 'el-select',
          optionList: [
            {
              name: '向上',
              label: '向上',
              value: 'up',
              code: 'up'
            }, {
              name: '向下',
              label: '向下',
              value: 'bottom',
              code: 'bottom'
            }, {
              name: '向左',
              label: '向左',
              value: 'left',
              code: 'left'
            }, {
              name: '向右',
              label: '向右',
              value: 'right',
              code: 'right'
            }
          ],
          attrConfig: {
            style: 'width:100%',
            controls: false,
            placeholder: '请选择弹窗位置'
          }
        },
        {
          name: ''
        },
        {
          name: '背景图',
          prop: 'backgroundImg',
          componentType: 'AddImg',
          attrConfig: { tip: '请上传jpg/png文件，且不超过5MB,建议尺寸1800px * 900px' }
        }, {
          name: ''
        },
        {
          name: '楼层信息',
          itemClass: 'lable-head'
        },
        {
          name: ''
        },
        {
          name: '开始楼层',
          prop: 'startNum',
          attrConfig: { placeholder: '请输入开始楼层' }
        },
        {
          name: '结束楼层',
          prop: 'endNum',
          attrConfig: { placeholder: '请输入结束楼层' }
        }
      ]
    }
  },
  created() {
    const body = {
      sceneProjectId: this.requestParams.sceneProjectId
    }
    if (this.popData.id) {
      body.id = this.popData.id
    }
    this.$api.sceneEdifice.getrange(body).then(res => {
      this.floorAreaMax = res.data.maxValue
    })
  },
  computed: {
    rules() {
      const validateNumber = (rule, value, callback) => {
        const numberReg = /^-?[0-9]\d*$/
        let msg = ''
        if (value !== '') {
          if (!numberReg.test(value)) {
            msg = '请输入整数'
          } else if (value === '0') {
            msg = '楼层数不能是0'
          }
        } else {
          msg = '请输入楼层数'
        }
        msg ? callback(new Error(msg)) : callback()
      }
      const rules = {
        sceneProjectId: [{ required: true, message: '请选择项目', trigger: 'blur' }],
        edificeName: [{ required: true, message: '请输入楼栋名称', trigger: 'blur' }],
        posX: [{ required: false, type: 'number', message: '请输入定点位置', trigger: 'blur' }],
        posY: [{ required: false, type: 'number', message: '请输入定点位置', trigger: 'blur' }],
        popPosition: [{ required: false, message: '请选择弹窗位置', trigger: 'blur' }],
        floorArea: [
          { required: true, message: '请输入建筑面积' },
          {
            min: 0,
            max: this.floorAreaMax,
            type: 'integer',
            message: '建筑面积在0~' + this.floorAreaMax + '之间',
            trigger: 'blur'
          }
        ],
        startNum: [{ required: true, trigger: 'blur', validator: validateNumber }],
        endNum: [{ required: true, trigger: 'blur', validator: validateNumber }]
      }
      for (let i = 0; i < this.floorList.length; i++) {
        // 楼层名称验证规则
        rules[`floor_${i}`] = [{
          required: true,
          trigger: 'blur',
          validator: (rule, value, callback) => {
            const index = rule.field.split('_')[1]
            const err = !this.floorList[index].floorName ? new Error('请输入楼层名称') : undefined
            callback(err)
          }
        }]
        rules[`floor_area_${i}`] = [{
          required: true,
          trigger: 'blur',
          validator: (rule, value, callback) => {
            const index = rule.field.split('_')[2]
            let err = undefined
            const val = this.floorList[index].floorArea
            if (val == null || val === '') {
              err = new Error('请输入建筑面积')
            }
            if (isNaN(val)) {
              err = new Error('请输入整数')
            }
            const total = this.floorList.map(item => item.floorArea)
              .reduce((accumulator, currentValue) => accumulator + currentValue, 0)
            if (this.formData.floorArea != null && total > this.formData.floorArea) {
              err = new Error('楼层建筑面积总和不能超过楼栋建筑面积')
            }
            callback(err)
          }
        }]
      }
      return rules
    }
  },
  watch: {
    popData: {
      handler(data) {
        this.isAdd = !data.id
        this.formList.forEach((e) => {
          this.$set(this.formData, e.prop, data[e.prop])
        })
        this.$set(this.formData, 'id', data.id)
        if (this.isAdd) {
          this.$set(this.formData, 'sceneProjectId', this.requestParams.sceneProjectId)
        }
        if (data.backgroundImg != null) {
          this.formList[12].attrConfig.defaultFileList = [data.backgroundImg]
        }
      },
      deep: true,
      immediate: true
    },
    confirm() {
      const params = {
        ...(this.formData || {})
      }
      this.submit(params)
    }
  },
  methods: {
    changeImg(key, value) {
      this.$set(this.formData, 'backgroundImgFile', value)
    },
    /**
     * change事件
     */
    handlerSelectData(config) {
      const Ref = this.$refs[config.prop]
      if (Ref && config.isClosePop) {
        Ref.dropDownVisible = false
      }
    },
    /**
     * 提交
     */
    submit(params) {
      this.$refs.form.validate(async (valid) => {
        if (valid && this.validateFloor()) {
          if (this.formData.backgroundImgFile) {
            const formData = new FormData()
            formData.append('file', this.formData.backgroundImgFile.raw)
            const urlRes = await this.$api.fileManage.baseUploadData(
              '/energy-carbon/grass-file/file/upload',
              formData
            )
            if (Number(urlRes.code) === 1000) {
              params.backgroundImg = urlRes.data
            }
          }
          params.floorJson = JSON.stringify(this.floorList)
          const res = await this.$api.sceneEdifice[this.isAdd ? 'add' : 'update'](params)
          if (Number(res.code) === 1000) {
            this.$message.success(`${this.isAdd ? '新增' : '编辑'}成功！`)
            this.$emit('onFinish', 'scene-edifice-add')
          }
        }
      })
    },
    /**
     * 生成楼层列表
     */
    generateFloorList() {
      const { startNum, endNum } = this.formData
      if (this.validateFloor()) {
        const newFloors = []
        let oldFloors = []
        if (this.floorList.length !== 0) {
          oldFloors = JSON.parse(JSON.stringify(this.floorList))
          this.floorList = []
        }
        for (let i = startNum; i <= endNum; i++) {
          if (i === 0) {
            continue
          }
          if (oldFloors.length > 0) {
            // 判断之前是否有这个楼层
            let has = false
            for (let j = 0; j < oldFloors.length; j++) {
              const item = oldFloors[j]
              if (i === item.floorNum) {
                newFloors.push(item)
                has = true
                break
              }
            }
            if (has) {
              // 存在的话继续下一层
              continue
            }
          }
          newFloors.push({
            floorNum: i,
            floorName: i + '层',
            floorArea: null
          })
        }
        if (this.formData.floorArea != null && newFloors.length > 0) {
          const avg = this.formData.floorArea / newFloors.length
          newFloors.forEach(item => {
            item.floorArea = avg
          })
        }
        this.floorList = newFloors
      }
    },
    /**
     * 验证开始楼层与结束楼层
     */
    validateFloor() {
      let { startNum, endNum } = this.formData
      startNum = parseInt(startNum)
      endNum = parseInt(endNum)
      if (isNaN(startNum) || isNaN(endNum)) {
        this.$message.error('开始楼层,结束楼层只能是数字')
        return false
      }
      if (startNum === 0 || endNum === 0) {
        this.$message.error('楼层数不能等于0')
        return false
      }
      if (!startNum || !endNum) {
        this.$message.error('请输入开始楼层和结束楼层')
        return false
      }
      if (startNum >= endNum) {
        this.$message.error('开始楼层不能大于或等于结束楼层')
        return false
      }
      return true
    },
    /**
     * 查询楼层列表
     */
    async getFloorList() {
      const res = await api.queryList({
        sceneEdificeId: this.formData.id,
        sortColumn: 'floorNum',
        sortOrder: 'asc'
      })
      this.floorList = res.data
    }
  },
  mounted() {
    if (!this.isAdd) {
      this.getFloorList()
    }
  }
}
</script>

<style lang="scss" scoped>
.scene-edifice-box {
  color: #333;
  padding: 0 20px;

  ::v-deep .el-form {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;

    .lable-head {
      .el-form-item__label {
        border-left-style: solid;
        border-left-width: 5px;
        border-left-color: var(--button-default-color);
        text-align: left;
        padding-left: 10px;
      }
    }

    .floor-input {
      color: #666;
      font-weight: bold;
      font-size: 14px;
      //margin-bottom: 30px;

      .input {
        line-height: 30px;
      }
    }

    .floor-div {
      max-height: 300px;
      overflow: auto;
    }

    .el-form-item {
      width: 50%;

      &.width100p {
        width: 100%;
      }

      .el-form-item__label {
        color: #666;
        font-size: 14px;
      }

      &.form-sub-title {
        width: 100%;

        .el-form-item__label {
          display: flex;
          align-items: center;
          justify-content: flex-start;
          font-weight: bold;
          color: #333;
          font-size: 16px;
          line-height: 1;

          &::before {
            content: '';
            display: inline-block;
            width: 4px;
            height: 15px;
            background-color: #00858d;
            margin-right: 5px;
          }
        }
      }
    }

    .el-select,
    .el-cascader {
      width: 100%;
    }
  }
}
</style>
